#include "qscriptobjectlistwidget.h"

#include "qscriptobjectlistwidgetbar.h"
#include "qpagewidget.h"

#include "../../lib/corelib/minisplitter.h"
#include "../../lib/corelib/qcommondelegate.h"

#include <QVBoxLayout>
#include <QHeaderView>
#include <QPalette>

QScriptObjectListWidget::QScriptObjectListWidget(QWidget *parent) :
    QWidget(parent),
    m_bar(new QScriptObjectListWidgetBar(this)),
    m_objectList(new QCommonTreeWidget(this)),
    m_functionList(new QListWidget(this))
{
    m_functionList->setItemDelegate(new QCommonDelegate());
    m_objectList->setItemDelegate(new QCommonDelegate());
    QVBoxLayout *v=new QVBoxLayout;
    v->setMargin(0);
    v->setSpacing(0);
    v->addWidget(m_bar);

    MiniSplitter *splitter=new MiniSplitter(Qt::Vertical);
    splitter->addWidget(m_objectList);
    splitter->addWidget(m_functionList);
    v->addWidget(splitter,1);
    this->setLayout(v);
    m_objectList->header()->setVisible(false);
    m_functionList->setFrameStyle(QFrame::NoFrame);
    m_objectList->setFrameStyle(QFrame::NoFrame);


    initObjectList();
    objectSelectChanged();
    connect(m_objectList,SIGNAL(itemSelectionChanged()),this,SLOT(objectSelectChanged()));
    connect(m_functionList,SIGNAL(itemDoubleClicked(QListWidgetItem*)),this,SLOT(functionSelect(QListWidgetItem*)));
    connect(m_bar,SIGNAL(findNext(QString)),this,SLOT(findNext(QString)));
    connect(m_bar,SIGNAL(findPrev(QString)),this,SLOT(findPrev(QString)));

    QPalette p=m_objectList->palette();
    p.setColor(QPalette::Inactive,QPalette::Highlight,p.color(QPalette::Active,QPalette::Highlight));
    p.setColor(QPalette::Inactive,QPalette::HighlightedText,p.color(QPalette::Active,QPalette::HighlightedText));
    m_objectList->setPalette(p);
    m_functionList->setPalette(p);

    m_functionList->setAlternatingRowColors(true);
    m_objectList->setAlternatingRowColors(true);
}

void QScriptObjectListWidget::initObjectList()
{
    m_forms.clear();
    QPageWidget *pagewidget=QPageWidget::pageWidget();

    QStringList pages=pagewidget->pages();
    QTreeWidgetItem* first=NULL;
    foreach(QString page,pages)
    {
        tagFormInfo info=pagewidget->pageMethod(page);
        QTreeWidgetItem *root=new QTreeWidgetItem(m_objectList);
        if(first==NULL)
        {
            first=root;
        }
        root->setText(0,page);
        root->setToolTip(0,page);
        foreach(tagWidgetInfo in,info.m_widgetInfo)
        {
            QTreeWidgetItem *item=new QTreeWidgetItem(root);
            item->setText(0,in.m_name);
            item->setToolTip(0,in.m_name);
        }
        m_forms.insert(info.m_name,info);
    }
    m_objectList->expandAll();
    if(first!=NULL)
    {
        first->setSelected(true);
    }
}

void QScriptObjectListWidget::objectSelectChanged()
{
    QList<QTreeWidgetItem*> items=m_objectList->selectedItems();

    QStringList pages=m_forms.keys();
    if(items.size()>0)
    {
        QList<tagFuncInfo> info;
        QTreeWidgetItem *item=items.first();
        QString str=item->text(0);
        if(pages.indexOf(str)>=0)
        {
            info=m_forms.value(str).m_funcInfo;
        }
        else
        {
            tagFormInfo in=m_forms.value(item->parent()->text(0));
            foreach(tagWidgetInfo winf,in.m_widgetInfo)
            {
                if(winf.m_name==str)
                {
                    info=winf.m_funcInfo;
                }
            }
        }
        m_functionList->clear();
        foreach(tagFuncInfo m,info)
        {
            m_functionList->addItem(m.m_method.signature());
        }
    }
}

void QScriptObjectListWidget::functionSelect(QListWidgetItem *item)
{
    QString func=item->text();

    QList<QTreeWidgetItem*> items=m_objectList->selectedItems();

    QStringList pages=m_forms.keys();

    QString text;
    if(items.size()>0)
    {
        QList<tagFuncInfo> info;
        QTreeWidgetItem *item=items.first();
        QString str=item->text(0);
        if(pages.indexOf(str)>=0)
        {
            info=m_forms.value(str).m_funcInfo;
            text=str;
        }
        else
        {
            tagFormInfo in=m_forms.value(item->parent()->text(0));
            foreach(tagWidgetInfo winf,in.m_widgetInfo)
            {
                if(winf.m_name==str)
                {
                    info=winf.m_funcInfo;
                    text=in.m_name+"."+str;
                }
            }
        }
        int count=0;
        QString type;
        foreach(tagFuncInfo in,info)
        {
            if(in.m_method.signature()==func)
            {
                count=in.m_method.parameterNames().size();
                type=in.m_method.typeName();
            }
        }
        if(text!="")
        {
            func=func.left(func.indexOf("("));
            text+=("."+func);
            emit selectFunction(text,count,type);
        }
    }

}

void QScriptObjectListWidget::findNext(const QString &text)
{
    QList<QTreeWidgetItem*> items=m_objectList->selectedItems();
    if(items.size()>0)
    {
        QTreeWidgetItem* item=items.first();
        QTreeWidgetItem* temp=item;
        if(temp->childCount()>0)
        {
            temp=temp->child(0);
        }
        else
        {
            if(temp->parent()->indexOfChild(temp)>=temp->parent()->childCount()-1)
            {
                temp=temp->parent()->child(0);
            }
            else
            {
                temp=temp->parent()->child(temp->parent()->indexOfChild(temp)+1);
            }
        }
        while(1)
        {
            if(temp==item)
            {
                break;
            }
            if(temp->text(0).indexOf(text)>=0)
            {
                item->setSelected(false);
                temp->setSelected(true);
                return;
            }
            if(temp->childCount()>0)
            {
                temp=temp->child(0);
            }
            else
            {
                if(temp->parent()->indexOfChild(temp)>=temp->parent()->childCount()-1)
                {
                    temp=temp->parent()->child(0);
                }
                else
                {
                    temp=temp->parent()->child(temp->parent()->indexOfChild(temp)+1);
                }
            }
        }
    }
}

void QScriptObjectListWidget::findPrev(const QString &text)
{
    QList<QTreeWidgetItem*> items=m_objectList->selectedItems();
    if(items.size()>0)
    {
        QTreeWidgetItem* item=items.first();
        QTreeWidgetItem* temp=item;
        if(temp->childCount()>0)
        {
            temp=temp->child(0);
        }
        else
        {
            if(temp->parent()->indexOfChild(temp)==0)
            {
                temp=temp->parent()->child(temp->parent()->childCount()-1);
            }
            else
            {
                temp=temp->parent()->child(temp->parent()->indexOfChild(temp)-1);
            }
        }
        while(1)
        {
            if(temp==item)
            {
                break;
            }
            if(temp->text(0).indexOf(text)>=0)
            {
                item->setSelected(false);
                temp->setSelected(true);
                return;
            }
            if(temp->childCount()>0)
            {
                temp=temp->child(0);
            }
            else
            {
                if(temp->parent()->indexOfChild(temp)==0)
                {
                    temp=temp->parent()->child(temp->parent()->childCount()-1);
                }
                else
                {
                    temp=temp->parent()->child(temp->parent()->indexOfChild(temp)-1);
                }
            }
        }
    }
}
